www.gusucode.com > VC++下的串行数据通信以及八个串口编程实例- > VC++下的串行数据通信以及八个串口编程实例-/第7章 智能安防报警系统/AlertView.cpp
// AlertView.cpp : implementation of the CAlertView class // #include "stdafx.h" #include "Alert.h" #include "AlertDoc.h" #include "AlertView.h" #include "WinIO.h" #include "CommSettingDlg.h" #include "SetParaDlg.h" #include "LogDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CAlertView IMPLEMENT_DYNCREATE(CAlertView, CFormView) BEGIN_MESSAGE_MAP(CAlertView, CFormView) //{{AFX_MSG_MAP(CAlertView) ON_WM_TIMER() ON_UPDATE_COMMAND_UI(ID_ALERT_START, OnUpdateAlertStart) ON_COMMAND(ID_ALERT_START, OnAlertStart) ON_COMMAND(ID_SETTINGS, OnSettings) ON_COMMAND(ID_LOG_MANAGE, OnLogManage) //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CFormView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CFormView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CFormView::OnFilePrintPreview) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CAlertView construction/destruction CAlertView::CAlertView() : CFormView(CAlertView::IDD) { //{{AFX_DATA_INIT(CAlertView) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // TODO: add construction code here } CAlertView::~CAlertView() { } void CAlertView::DoDataExchange(CDataExchange* pDX) { CFormView::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAlertView) DDX_Control(pDX, IDC_LIST_TODAY, m_logList); DDX_Control(pDX, IDC_MSCOMM1, m_Comm1); DDX_Control(pDX, IDC_MSCOMM2, m_Comm2); //}}AFX_DATA_MAP } BOOL CAlertView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs return CFormView::PreCreateWindow(cs); } void CAlertView::OnInitialUpdate() { CFormView::OnInitialUpdate(); GetParentFrame()->RecalcLayout(); ResizeParentToFit(); m_logList.InsertColumn(0,"布控名称"); m_logList.InsertColumn(1,"时间"); m_logList.InsertColumn(2,"动作"); CRect rect; m_logList.GetClientRect(&rect); m_logList.SetColumnWidth(0,rect.Width()/5); m_logList.SetColumnWidth(1,rect.Width()*2/5); m_logList.SetColumnWidth(2,rect.Width()*2/5); CTime date=CTime::GetCurrentTime(); CString strDate=date.Format("%Y-%m-%d"); CString strSql="select * from log where date >= #"+strDate+"#"; m_bstrSQL = strSql.AllocSysString(); m_pRsLog.CreateInstance(_uuidof(Recordset)); //初始化Recordset指针 CAlertApp* pApp=(CAlertApp*)::AfxGetApp(); //adOpenStatic:静态 adLockOptimistic乐观封锁法 adCmdText:文本查询语句 m_pRsLog->Open(m_bstrSQL,(IDispatch*)pApp->m_pConnection,adOpenStatic,adLockOptimistic,adCmdText); m_cntLog = m_pRsLog->RecordCount; ShowLog(); //显示日志表中今日的记录 m_pRsLog->Close(); m_pRsLog=NULL; initcpara(); //初始化端口 //启动检测系统 m_bAction=FALSE; m_nTimer = SetTimer(1, 5000, 0); } ///////////////////////////////////////////////////////////////////////////// // CAlertView printing BOOL CAlertView::OnPreparePrinting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); } void CAlertView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing } void CAlertView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add cleanup after printing } void CAlertView::OnPrint(CDC* pDC, CPrintInfo* /*pInfo*/) { // TODO: add customized printing code here } ///////////////////////////////////////////////////////////////////////////// // CAlertView diagnostics #ifdef _DEBUG void CAlertView::AssertValid() const { CFormView::AssertValid(); } void CAlertView::Dump(CDumpContext& dc) const { CFormView::Dump(dc); } CAlertDoc* CAlertView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CAlertDoc))); return (CAlertDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CAlertView message handlers void CAlertView::ShowLog() { if(m_pRsLog==NULL) return; int i=0; CString strText; _variant_t bfname,date,time,cjname; //VARIANT数据类型 m_logList.DeleteAllItems(); if(!m_pRsLog->RecordCount) return; m_pRsLog->MoveFirst(); while(!m_pRsLog->adoEOF)//遍历所有记录 { // strText.Format(TEXT("item %d"), i); int nItem; bfname = m_pRsLog->GetCollect("bfname");//得到字段"bfname"的值 if(bfname.vt!=VT_NULL) nItem=m_logList.InsertItem(0,_bstr_t(bfname)); date = m_pRsLog->GetCollect("date"); //得到字段"date"的值 time = m_pRsLog->GetCollect("time"); //得到字段"time"的值 if(date.vt!=VT_NULL && time.vt!=VT_NULL) m_logList.SetItemText(nItem,1,_bstr_t(date)+_bstr_t(" ")+_bstr_t(time)); cjname = m_pRsLog->GetCollect("cjname");//得到字段"cjname"的值 if(cjname.vt!=VT_NULL) m_logList.SetItemText(nItem,2,_bstr_t(cjname)); m_pRsLog->MoveNext();//转到下一条纪录 i++; } } void CAlertView::initcpara() { TRY { initcom(); //初始化串口 } CATCH(CException,e) { e->ReportError(); } END_CATCH BOOL bResult = InitializeWinIo(); //初始化WinIO库 if (!bResult) { ::AfxMessageBox("WINIO库初始化失败"); } getLpt(); //从数据库中得到可以使用的并口编号,并赋予数组lptPort } void CAlertView::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default if(nIDEvent==1) { if(m_bAction==TRUE) { SpyOn(); //对布防设置进行监控 updateLog(); //更新日志 } } CFormView::OnTimer(nIDEvent); } void CAlertView::OnUpdateAlertStart(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here pCmdUI->SetCheck(m_bAction); } void CAlertView::OnAlertStart() { // TODO: Add your command handler code here m_bAction=!m_bAction; //工具栏图标问题未处理 } //监控子程序:从各监控端口取数据判断触发事件是否发生,并给以处警 void CAlertView::SpyOn() { if(m_lptInbf) { for(int i=0;i<lptPortArray.GetSize();i++) { DWORD portVal; GetPortVal(lptPortArray[i], &portVal, 1); processLook((BYTE)portVal, FALSE); } } } //提取端口内容,判断触发事件的发生,找出对应设置响应,并记录入日志 void CAlertView::processLook(BYTE br, BOOL c) { CString s; if(c) s = "select * from bufangset where property='串口'"; else s = "select * from bufangset where property='并口'"; _RecordsetPtr r; r.CreateInstance(_uuidof(Recordset)); CAlertApp* pApp=(CAlertApp*)::AfxGetApp(); //adOpenStatic:静态 adLockOptimistic乐观封锁法 adCmdText:文本查询语句 _bstr_t bs=s.AllocSysString(); r->Open(bs,(IDispatch*)pApp->m_pConnection,adOpenStatic,adLockOptimistic,adCmdText); if(r->RecordCount==0) goto finish; r->MoveFirst(); while(!r->adoEOF) { //若有事件发生,则响应该触发事件 CString s1,s2; _bstr_t bs1,bs2; _bstr_t bfname,cjname; _RecordsetPtr r1,r2; int count; BYTE bfcode= BYTE(r->GetCollect("bfcode")); bfname= _bstr_t(r->GetCollect("bfname")); if(!br || bfcode!= br) continue; //找出对应处警设置 r1.CreateInstance(_uuidof(Recordset)); bs1="select cjname from bftocj where bfname = '" +bfname +"'"; r1->Open(bs1,(IDispatch*)pApp->m_pConnection,adOpenStatic,adLockOptimistic,adCmdText); cjname=_bstr_t(r1->GetCollect("cjname")); CString temp=LPTSTR(cjname); count=analystRs(temp); //记入日志 r2.CreateInstance(_uuidof(Recordset)); s2="select cjname from log"; bs2=s2.AllocSysString(); r2->Open(bs2,(IDispatch*)pApp->m_pConnection,adOpenDynamic,adLockOptimistic,adCmdText); r2->AddNew(); r2->PutCollect("bfname",bfname); r2->PutCollect("cjname",cjname); COleDateTime t=COleDateTime::GetCurrentTime(); t.Format("%Y-%m-%d"); r2->PutCollect("date",COleVariant(t)); t.Format("%H:%M:%S"); r2->PutCollect("time",COleVariant(t)); r2->Update(); r2->Close(); r1->Close(); r2=r1=NULL; //予以处警响应 for(int i=0;i<count;i++) { r1.CreateInstance(_uuidof(Recordset)); bs1="select * from chujingset where cjname = '" +strcj[i] +"'"; r1->Open(bs1,(IDispatch*)pApp->m_pConnection,adOpenStatic,adLockOptimistic,adCmdText); while(!r1->adoEOF) { _bstr_t property=_bstr_t(r1->GetCollect("property")); if(property==_bstr_t("串口")) { if(m_Comm1.GetPortOpen()) { char telnum[20]; itoa(long(r1->GetCollect("telnumber")),telnum,10); char out[100]; strcpy(out,"ATDT"); strcat(out,telnum); int len=strlen(out); out[len]=0x0d; out[len+1]=0x0a; out[len+2]=0; m_Comm1.SetOutput(_variant_t(out)); } } if(property==_bstr_t("并口")) { BOOL res; _bstr_t typeact=_bstr_t(r1->GetCollect("typeact")); if(typeact==_bstr_t("拨号")) res=SetPortVal(long(r1->GetCollect("number")),long(r1->GetCollect("telnumber")),1); //只写一字节? else //发码 res=SetPortVal(long(r1->GetCollect("number")),long(r1->GetCollect("infocode")),1); if(res==FALSE) ::AfxMessageBox("WinIO 库未成功安装"); } r1->MoveNext(); } r1->Close(); r1=NULL; } r->MoveNext(); } finish: r->Close(); r=NULL; } //触发器源+事件+处警动作 //日志更新 void CAlertView::updateLog() { m_pRsLog.CreateInstance(_uuidof(Recordset)); //初始化Recordset指针 CAlertApp* pApp=(CAlertApp*)::AfxGetApp(); //adOpenStatic:静态 adLockOptimistic乐观封锁法 adCmdText:文本查询语句 m_pRsLog->Open(m_bstrSQL,(IDispatch*)pApp->m_pConnection,adOpenStatic,adLockOptimistic,adCmdText); if(m_cntLog!=m_pRsLog->RecordCount) { m_cntLog=m_pRsLog->RecordCount; //显示日志表中今日的记录 ShowLog(); } m_pRsLog->Close(); m_pRsLog=NULL; } int CAlertView::analystRs(CString cjname) { int count=0; //count:纪录获取的字符串个数 strcj.RemoveAll(); strcj.Add(""); for(int i=0;i<cjname.GetLength();i++) { if(cjname[i]!='@') strcj[count]+=cjname[i]; else { count+=1; strcj.Add(""); } } if(strcj[count]=="") { strcj.RemoveAt(count); count--; } return count+1; } //初始化COM口 void CAlertView::initcom() { //初始化处警拨号使用的com口(控件:mscomm1) _RecordsetPtr r; r.CreateInstance(_uuidof(Recordset)); CString s= "select distinct number from chujingset where property='串口'"; _bstr_t bs=s.AllocSysString(); CAlertApp* pApp=(CAlertApp*)::AfxGetApp(); //adOpenStatic:静态 adLockOptimistic乐观封锁法 adCmdText:文本查询语句 r->Open(bs,(IDispatch*)pApp->m_pConnection,adOpenStatic,adLockOptimistic,adCmdText); CString strcom,commSetting,commHandShaking; int commport = (BYTE)r->GetCollect("number"); //处警表里面使用的com口端口号 itoa(commport,strcom.GetBuffer(10),10); strcom.ReleaseBuffer(); r->Close(); r=NULL; commSetting = GetSetting(CString("PortSetting\\Com")+strcom+"\\", "commSetting"); commHandShaking = GetSetting(CString("PortSetting\\Com")+strcom+"\\", "commHandshaking"); while((commSetting=="")||(commHandShaking=="")) { CCommSettingDlg dlg; dlg.m_strChoose=CString("串口")+strcom; dlg.DoModal(); commSetting = GetSetting(CString("PortSetting\\Com")+strcom+"\\", "commSetting"); commHandShaking = GetSetting(CString("PortSetting\\Com")+strcom+"\\", "commHandshaking"); } m_Comm1.SetCommPort(commport); long shakehand=atol(commHandShaking.GetBuffer(50)); commHandShaking.ReleaseBuffer(); m_Comm1.SetSettings(commSetting); m_Comm1.SetHandshaking(shakehand); TRY { m_Comm1.SetPortOpen(TRUE); } CATCH(CException,e) { e->ReportError(); } END_CATCH //如果布防设置中使用到com口的话,则初始化该com口 //控件:mscomm2 r.CreateInstance(_uuidof(Recordset)); s="select distinct number from bufangset where property='串口'"; bs=s.AllocSysString(); r->Open(bs,(IDispatch*)pApp->m_pConnection,adOpenStatic,adLockOptimistic,adCmdText); commport = (BYTE)r->GetCollect("number"); //布防表里使用的com口端口号 itoa(commport,strcom.GetBuffer(10),10); strcom.ReleaseBuffer(); if(r->RecordCount==1) { m_comInbf=TRUE; commSetting = GetSetting(CString("PortSetting\\Com")+strcom+"\\", "commSetting"); commHandShaking = GetSetting(CString("PortSetting\\Com")+strcom+"\\", "commHandshaking"); while((commSetting=="")||(commHandShaking=="")) { CCommSettingDlg dlg; dlg.m_strChoose=CString("串口")+strcom; dlg.DoModal(); commSetting = GetSetting(CString("PortSetting\\Com")+strcom+"\\", "commSetting"); commHandShaking = GetSetting(CString("PortSetting\\Com")+strcom+"\\", "commHandshaking"); } m_Comm2.SetCommPort(commport); shakehand=atol(commHandShaking.GetBuffer(50)); commHandShaking.ReleaseBuffer(); m_Comm2.SetSettings(commSetting); m_Comm2.SetHandshaking(shakehand); m_Comm2.SetInputMode(1); m_Comm2.SetPortOpen(TRUE); } else m_comInbf=FALSE; r->Close(); r=NULL; } void CAlertView::getLpt() { _RecordsetPtr r; r.CreateInstance(_uuidof(Recordset)); CString s="select distinct number from bufangset where property='并口' and promote=true"; _bstr_t bs=s.AllocSysString(); CAlertApp* pApp=(CAlertApp*)::AfxGetApp(); r->Open(bs,(IDispatch*)pApp->m_pConnection,adOpenStatic, adLockOptimistic, adCmdText); //若在布防设置表中select出的并口项数量为零则判断系统不使用并口,反之使用 lptPortArray.RemoveAll(); if(r->RecordCount==0) m_lptInbf=FALSE; else { //若有并口则开一个并口端口数组,并给数组赋值 m_lptInbf=TRUE; TRY { r->MoveFirst(); for(int i=0; i<r->RecordCount; i++) { lptPortArray.Add((long)r->GetCollect("Number")); r->MoveNext(); } } CATCH(CException,e) { e->ReportError(); } END_CATCH } r->Close(); r=NULL; } BEGIN_EVENTSINK_MAP(CAlertView, CFormView) //{{AFX_EVENTSINK_MAP(CAlertView) ON_EVENT(CAlertView, IDC_MSCOMM2, 1 /* OnComm */, OnOnCommMscomm2, VTS_NONE) //}}AFX_EVENTSINK_MAP END_EVENTSINK_MAP() void CAlertView::OnOnCommMscomm2() { // TODO: Add your control notification handler code here if(m_Comm2.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符 { CString str=VARIANT2str(m_Comm2.GetInput()); for(int i=0; i<str.GetLength();i++) processLook(str[i],TRUE); } } void CAlertView::OnSettings() { // TODO: Add your command handler code here m_bAction=FALSE; CSetParaDlg dlg; dlg.DoModal(); // m_bAction=TRUE; } void CAlertView::OnLogManage() { // TODO: Add your command handler code here CLogDlg dlg(this); dlg.DoModal(); }